package com.inspur.dgov.vlbod.weixin;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class WeiXinService {

    private static String WEIXIN_TOKEN_KEY = "weixin_token_";

    private static String WEIXIN_TICKET_KEY = "weixin_ticket_";

    /**
     * 微信配置的应用id
     */
    @Value("${dgov.weixin.appId:}")
    private String appId;

    /**
     * 微信配置的应用秘钥
     */
    @Value("${dgov.weixin.appSecret:}")
    private String appSecret;

    /**
     * 微信接口地址
     */
    @Value("${dgov.weixin.api.url:}")
    private String apiUrl;

    /**
     * 微信令牌接口地址
     */
    @Value("${dgov.weixin.api.token:}")
    private String apiToken;

    /**
     * 微信用户标识接口地址
     */
    @Value("${dgov.weixin.api.user:}")
    private String apiUser;

    /**
     * 微信用户信息接口地址
     */
    @Value("${dgov.weixin.api.userDetail:}")
    private String apiUserDetail;

    /**
     * 微信ticket接口地址
     */
    @Value("${dgov.weixin.api.ticket:}")
    private String apiTicket;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 获取山东通平台令牌
     *
     * @return
     * @throws RuntimeException
     */
    public JSONObject getToken() throws RuntimeException {
        if (redisTemplate.hasKey(WEIXIN_TOKEN_KEY + appId)) {
            String token = (String) redisTemplate.opsForValue().get(WEIXIN_TOKEN_KEY + appId);
            return JSON.parseObject(token);
        }
        JSONObject tokenJson;
        try {
            String tokenRes = HttpUtil.get(apiUrl + apiToken + "?corpid=" + appId + "&corpsecret=" + appSecret, 5000);
            tokenJson = JSON.parseObject(tokenRes);
            int errcode = tokenJson.getIntValue("errcode");
            if (0 == errcode) {
                redisTemplate.opsForValue().set(WEIXIN_TOKEN_KEY + appId, tokenRes, tokenJson.getIntValue("expires_in"), TimeUnit.SECONDS);
            } else {
                log.error("山东通平台令牌获取失败:" + tokenJson.getString("errmsg"));
                throw new RuntimeException("山东通平台令牌获取失败:" + tokenJson.getString("errmsg"));
            }
        } catch (JSONException e) {
            log.error("山东通平台令牌获取失败:" + e.getMessage());
            throw new RuntimeException("山东通平台令牌获取失败:" + e.getMessage());
        }
        return tokenJson;
    }

    /**
     * 获取山东通平台登录用户标识
     *
     * @param code
     * @param accessToken
     * @return
     * @throws RuntimeException
     */
    public JSONObject getUserId(String code, String accessToken) throws RuntimeException {
        JSONObject user;
        try {
            String userRes = HttpUtil.get(apiUrl + apiUser + "?access_token=" + accessToken + "&code=" + code, 5000);
            JSONObject userJson = JSON.parseObject(userRes);
            int errcode = userJson.getIntValue("errcode");
            if (0 == errcode) {
                user = userJson;
            } else {
                log.error("山东通平台用户标识获取失败:" + userJson.getString("errmsg"));
                throw new RuntimeException("山东通平台登录用户标识获取失败:" + userJson.getString("errmsg"));
            }
        } catch (JSONException e) {
            log.error("山东通平台用户标识获取失败:" + e.getMessage());
            throw new RuntimeException("山东通平台登录用户标识获取失败:" + e.getMessage());
        }
        return user;
    }

    /**
     * 获取山东通平台用户详细信息
     *
     * @param userId
     * @param accessToken
     * @return
     * @throws RuntimeException
     */
    public JSONObject getUserDetail(String userId, String accessToken) throws RuntimeException {
        JSONObject user;
        try {
            String userDetailRes = HttpUtil.get(apiUrl + apiUserDetail + "?access_token=" + accessToken + "&userid=" + userId, 5000);
            JSONObject userDetailJson = JSON.parseObject(userDetailRes);
            int errcode = userDetailJson.getIntValue("errcode");
            if (0 == errcode) {
                user = userDetailJson;
            } else {
                log.error("山东通平台用户详细信息获取失败:" + userDetailJson.getString("errmsg"));
                throw new RuntimeException("山东通平台用户详细信息获取失败");
            }
        } catch (JSONException e) {
            log.error("山东通平台用户详细信息获取失败:" + e.getMessage());
            throw new RuntimeException("山东通平台用户详细信息获取失败:" + e.getMessage());
        }
        return user;
    }

    /**
     * 获取山东通平台JS接口的临时票据
     *
     * @return
     * @throws Exception
     */
    public JSONObject getTicket() throws RuntimeException {
        if (redisTemplate.hasKey(WEIXIN_TICKET_KEY + appId)) {
            String ticket = (String) redisTemplate.opsForValue().get(WEIXIN_TICKET_KEY + appId);
            return JSON.parseObject(ticket);
        }
        JSONObject ticketJson;
        try {
            JSONObject tokenJson = this.getToken();
            //获取jsapi_ticket（7200秒，redis存储）
            log.warn(apiUrl + apiTicket + "?access_token=" + tokenJson.getString("access_token"));
            String ticketRes = HttpUtil.get(apiUrl + apiTicket + "?access_token=" + tokenJson.getString("access_token"), 5000);
            log.warn(ticketRes);
            ticketJson = JSON.parseObject(ticketRes);
            int errcode = ticketJson.getIntValue("errcode");
            if (0 == errcode) {
                redisTemplate.opsForValue().set(WEIXIN_TICKET_KEY + appId, ticketRes, ticketJson.getIntValue("expires_in"), TimeUnit.SECONDS);
            } else {
                log.error("山东通平台临时票据获取失败:" + ticketJson.getString("errmsg"));
                throw new RuntimeException("山东通平台临时票据获取失败");
            }
        } catch (JSONException e) {
            log.error("山东通平台临时票据获取失败:" + e.getMessage());
            throw new RuntimeException("山东通平台临时票据获取失败");
        }
        return ticketJson;
    }
}
